<?php

/**
 * This is the model class for table "permission".
 *
 * The followings are the available columns in table 'permission':
 * @property integer $id
 * @property integer $pid
 * @property string $type
 * @property string $authtype
 * @property string $status
 * @property string $name
 * @property string $action
 * @property string $remark
 *
 * The followings are the available model relations:
 * @property Role[] $roles
 */
class Permission extends CActiveRecord
{
    const TYPE_GENERAL = 'general';
    const TYPE_MENU = 'menu';
    const TYPE_AJAX = 'ajax';
    const TYPE_API = 'api';
    const AUTHTYPE_FREE = 'free';
    const AUTHTYPE_ADMIN = 'admin';
    const AUTHTYPE_DEFINE = 'define';
    const STATUS_NORMAL = 'normal';
    const STATUS_DISABLE = 'disable';

    public $searchKey = '';

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'permission';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('type, authtype, status, name, action, pid,', 'required'),
            array('pid', 'numerical', 'integerOnly' => true),
            array('type, authtype, status', 'length', 'max' => 32),
            array('name, action', 'length', 'max' => 256),
            array('remark', 'safe'),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('id, pid, type, authtype, status, name, action, remark, searchKey', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'subs' => array(self::HAS_MANY, 'Permission', 'pid'),
            'roles' => array(self::MANY_MANY, 'Role', 'role_permission(pid, rid)'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'pid' => '父权限',
            'type' => '类型',
            'authtype' => '授权类型',
            'status' => '状态',
            'name' => '名称',
            'action' => '动作',
            'remark' => '备注',
            'searchKey' => '搜索关键词',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     *
     * Typical usecase:
     * - Initialize the model fields with values from filter form.
     * - Execute this method to get CActiveDataProvider instance which will filter
     * models according to data in model fields.
     * - Pass data provider to CGridView, CListView or any similar widget.
     *
     * @return CActiveDataProvider the data provider that can return the models
     * based on the search/filter conditions.
     */
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('pid', $this->pid);
        $criteria->compare('type', $this->type, true);
        $criteria->compare('authtype', $this->authtype, true);
        $criteria->compare('status', $this->status, true);
        $criteria->compare('name', $this->name, true);
        $criteria->compare('action', $this->action, true);
        $criteria->compare('remark', $this->remark, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    public function searchByKey()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.
        $criteria = new CDbCriteria;
        if ($this->searchKey !== '') {
            $criteria->addSearchCondition('name', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('action', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('type', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('authtype', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('status', $this->searchKey, true, 'OR');
            $criteria->addSearchCondition('remark', $this->searchKey, true, 'OR');
        }
        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

    /**
     * Returns the static model of the specified AR class.
     * Please note that you should have this exact method in all your CActiveRecord descendants!
     * @param string $className active record class name.
     * @return Permission the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public static function getPermissionTree($inputName = '', $inputId = '', $on = array(), $htmlOptions = array())
    {
        $permTree = array();
        $pars = self::model()->findAll('pid = 0');
        foreach ($pars as $par) {
            $permTree[$par->id]['name'] = $par->name;
            $permTree[$par->id]['authtype'] = $par->authtype;
            $permTree[$par->id]['status'] = $par->status;
            $permTree[$par->id]['sub'] = array();
        }
        $subs = self::model()->findAll('pid != 0');
        foreach ($subs as $sub) {
            if (isset($permTree[$sub->pid])) {
                $permTree[$sub->pid]['sub'][$sub->id]['name'] = $sub->name;
                $permTree[$sub->pid]['sub'][$sub->id]['authtype'] = $sub->authtype;
                $permTree[$sub->pid]['sub'][$sub->id]['status'] = $sub->status;
            }
        }
        $element = '';
        $element .= '<div id="role_perm_tree">';
        foreach ($permTree as $parId => $parNode) {
            $isNeed = false;
            $checked = false;
            $disabled = false;
            switch ($parNode['authtype']) {
                case self::AUTHTYPE_DEFINE:
                    $isNeed = true;
                    $checked = in_array($parId, $on);
                    $disabled = false || isset($htmlOptions['disabled']);
                    break;
                case self::AUTHTYPE_ADMIN:
                case self::AUTHTYPE_FREE:
                    foreach ($parNode['sub'] as $subId => $subNode) {
                        if ($subNode['authtype'] == Permission::AUTHTYPE_DEFINE) {
                            $isNeed = true;
                            break;
                        }
                    }
                    $checked = false;
                    $disabled = true;
                    break;
            }

            if ($isNeed) {
                $element .= '<div class="tree-branch" style="padding-left:20px;">';
                $element .= '<div class="checkbox">';
                $element .= '<label>';
                $element .= CHtml::checkBox($inputName, $checked, array('id' => $inputId . '_par', 'value' => $parId, 'class' => 'par_perm', 'disabled' => $disabled));
                $element .= '<a class="tree-branch-master" href="javascript:void(0)"><i class="fa fa-gears"></i>' . $parNode['name'] . '</a>';
                $element .= '</label>';
                $element .= '</div>';
                if (!empty($parNode['sub'])) {
                    $element .= '<div class="tree-branch-subs" style="padding-left:20px;">';
                    foreach ($parNode['sub'] as $subId => $subNode) {
                        switch ($subNode['authtype']) {
                            case self::AUTHTYPE_DEFINE:
                                $element .= '<div class="checkbox">';
                                $element .= '<label>';
                                $element .= CHtml::checkBox($inputName, in_array($subId, $on), array('id' => $inputId . '_par', 'value' => $subId, 'class' => 'par_perm', 'disabled' => (isset($htmlOptions['disabled']))));
                                $element .= '<a href="javascript:void(0)"><i class="fa fa-gear"></i>' . $subNode['name'] . '</a>';
                                $element .= '</label>';
                                $element .= '</div>';
                                break;
                        }
                    }
                    $element .= '</div>';
                }
                $element .= '</div>';
            }
        }
        $element .= '</div>';
        $element .= '<script type="text/javascript">';
        $element .= '$(function($) {';
        $element .= '	$("#role_perm_tree a.tree-branch-master").click(function(e){';
        $element .= '		$(this).parents(".tree-branch").children(".tree-branch-subs").toggle("fast");';
        $element .= '	});';
        $element .= '});';
        $element .= '</script>';
        return $element;
    }

    public static function getMenuPermission()
    {
        $permissions = array();
        $freePermissions = Permission::model()->findAll('authtype = :authtype AND type = :type', array(':authtype' => self::AUTHTYPE_FREE, 'type' => self::TYPE_MENU));
        foreach ($freePermissions as $permission) {
            $permissions[$permission->id] = $permission;
        }
        if (!Yii::app()->user->getIsGuest()) {
            $rid = Yii::app()->user->getState('rid');
            $role = Role::model()->with('permissions')->findByPk($rid);
            $rolePermissions = $role->permissions;
            foreach ($rolePermissions as $permission) {
                if ($permission->type = self::TYPE_MENU) {
                    $permissions[$permission->id] = $permission;
                }
            }
            $adminPermissions = Permission::model()->findAll('authtype = :authtype AND type = :type', array(':authtype' => self::AUTHTYPE_ADMIN, 'type' => self::TYPE_MENU));
            $isAdmin = Yii::app()->user->isAdmin();
            if ($isAdmin) {
                foreach ($adminPermissions as $permission) {
                    if (!isset($permissions[$permission->id])) {
                        $permissions[$permission->id] = $permission;
                    }
                }
            } else {
                foreach ($adminPermissions as $permission) {
                    if (isset($permissions[$permission->id])) {
                        unset($permissions[$permission->id]);
                    }
                }
            }
        }
        return $permissions;
    }

    public static function getOpUserPermissions()
    {
        $permissions = array();
        if (Yii::app()->user->isGuest) {
            $items = Permission::model()->findAllByAttributes(array('authtype' => self::AUTHTYPE_FREE));
            foreach ($items as $item){
                $permissions[$item->action] = $item->attributes;
            }
        } else {
            if (Yii::app()->user->isAdmin()) {
                $items = Permission::model()->findAll();
                foreach ($items as $item){
                    $permissions[$item->action] = $item->attributes;
                }
            } else {
                $rid= Yii::app()->user->getState('rid');
                $rid= empty($rid)?User::model()->findByAttributes(['name'=>Yii::app()->user->id])->role->id:$rid;
                $role = Role::model()->with('permissions')->findByPk($rid);
                Yii::app()->user->setState('rid',$rid);
                foreach ($role->permissions as $item){
                    $permissions[$item->action] = $item->attributes;
                }
                $freeItems = Permission::model()->findAllByAttributes(array('authtype' => self::AUTHTYPE_FREE));
                foreach ($freeItems as $item){
                    $permissions[$item->action] = $item->attributes;
                }

                $adminItems = Permission::model()->findAllByAttributes(array('authtype' => self::AUTHTYPE_ADMIN));
                foreach ($adminItems as $item){
                    unset($permissions[$item->action]);
                }
            }
        }
        return $permissions;
    }

    public static function getOptions($attribute = '')
    {
        $options = array();
        switch ($attribute) {
            case 'status':
                $options = array(
                    self::STATUS_NORMAL => self::STATUS_NORMAL,
                    self::STATUS_DISABLE => self::STATUS_DISABLE,
                );
                break;
            case 'type':
                $options = array(
                    self::TYPE_GENERAL => self::TYPE_GENERAL,
                    self::TYPE_MENU => self::TYPE_MENU,
                    self::TYPE_API => self::TYPE_API,
                    self::TYPE_AJAX => self::TYPE_AJAX,
                );
                break;
            case 'authtype':
                $options = array(
                    self::AUTHTYPE_ADMIN => self::AUTHTYPE_ADMIN,
                    self::AUTHTYPE_DEFINE => self::AUTHTYPE_DEFINE,
                    self::AUTHTYPE_FREE => self::AUTHTYPE_FREE,
                );
                break;
            case 'pid':
                $options[0] = '==========';
                $pars = self::model()->findAllByAttributes(array('pid' => 0));
                foreach ($pars as $par) {
                    $options[$par->id] = $par->name;
                }
                break;
        }
        return $options;
    }
}
